import React, { useEffect, useState, useMemo, useRef, useCallback, useImperativeHandle } from 'react'
import lodash from 'lodash'
import { observer } from '@formily/react'
import { InbizIcon } from '@inbiz/utils'
import { TextWidget, getMessage } from '@inbiz/react'
import { Popover, Select, Typography, Empty, Spin } from 'antd'
import { getFolderId } from './utils'
import { getPaths, getEcmTeams } from './service'
import './index.less'

const { Option } = Select
export default observer((props: any) => {
  // searchResult代表在搜索结果组件
  const { onChange, value: _value, configEvents, params, topPersonalFolderId, advancedSearch, config, searchEngineData,
    pathkey, showTeam, showPerson, searchResult, ref, getMetaSearchArr, buildInSearchParams, pathValue, $pathValue } = props
  const { parentFolderLevel, parentTopFolderId, parentFolderid, parentFolderPath } = searchEngineData || {}

  // @@ 可能会有问题
  const value = _value || pathValue

  const topFolder = [{
    name: 'BelongDirectory.enterprise',
    iconType: 'icon-system-tree-tuanduiku',
    id: '1',
    parentId: '0',
    folderPath: '1\\',
  }, {
    name: 'BelongDirectory.team',
    iconType: 'icon-system-tree-team2',
    id: '7',
    parentId: '0',
    folderPath: '7\\',
  }, {
    name: 'BelongDirectory.person',
    iconType: 'icon-system-tree-gerenku',
    id: String(topPersonalFolderId),
    parentId: '0',
    folderPath: `${topPersonalFolderId}\\`,
  }]
  const [childFolder, $childFolder] = useState([])
  const [topFolderId, $topFolderId] = useState(parentTopFolderId || '1')
  const [currentFolderId, $currentFolderId] = useState('1')
  const folderLevel = useRef(parentFolderLevel || 2)
  const [topfolderItem, $topfolderItem] = useState({});
  const [allData, $allData] = useState(topFolder)
  const [loading, $loading] = useState(false)

  useEffect(() => {
    if (parentTopFolderId) {
      $topFolderId(parentTopFolderId)
    }
  }, [parentTopFolderId])

  const getTeams = (type?) => {
    $loading(true)
    return getEcmTeams().then(res => {
      if (res.result == 0) {
        const newFolders = res.teamList.map(item => {
          return {
            ...item,
            id: item.folderId,
            Name: item.teamName,
            parentId: 7,
            folderPath: `7\\${item.folderId}`
          }
        })
        $childFolder(newFolders)
        if (!type) {
          $allData(data => {
            return lodash.uniq([...data, ...newFolders])
          })
        }
        $loading(false)
        return newFolders
      } else {
        $loading(false)

      }
    })
  }

  /**
   * 返回上一级
   * 根据parentId查找
   */
  const backLastLevel = async () => {
    const folderPathArr = value.folderPath.split('\\').filter(ele => ele)
    if (folderPathArr.length > 1) {
      folderPathArr.splice(folderPathArr.length - 1, 1)
    }
    const folderPathString = folderPathArr.join('\\')
    const i = folderPathArr.findIndex(ele => ele == currentFolderId)
    let j = 0
    if (i > 0) {
      j = i - 1
    }
    $currentFolderId(folderPathArr[j])
    folderLevel.current = value.folderLevel - 1
    const parentData = allData.find(ele => ele.id == currentFolderId) || {}

    if (folderPathArr.length == 1 && folderPathArr[0] == '7') {
      await getTeams('1')

      onChange({
        value: [{
          folderid: currentFolderId
        }],
        name: parentData.teamName || getMessage(parentData.name),
        label: 'SearchEngine.folderIn',
        key: pathkey,
        folderPath: folderPathString,
        type: 'back',
        folderLevel: folderLevel.current,
        topFolderId,
        controlType: 'edoc2SelectFolder'
      })
    } else {
      let metaSearchWhere = []

      if (searchResult) {
        if (params.IndexName == 'folder') {
          metaSearchWhere = getMetaSearchArr({
            path: `(folderpath:${currentFolderId} AND NOT folderid:${currentFolderId})`,
            sourceUser: buildInSearchParams.sourceUser
          })
        } else {
          metaSearchWhere = getMetaSearchArr({
            path: `(filepath:${currentFolderId} AND NOT folderid:${currentFolderId})`,
            sourceUser: buildInSearchParams.sourceUser
          })
        }
      }

      const SearchWhere = [config.resultsSearchCriteria, ...metaSearchWhere, params.categorySearchWhere]
        .filter((item) => !!item)
        .join(' AND ')

      await getChildFolder({
        level: value.folderLevel - 1, fileSearchid: topFolderId, searchFolderId: currentFolderId, folderPath: folderPathString, newParams: {
          ...params,
          SearchWhere
        }
      }, '1')
      onChange({
        value: [{
          folderid: currentFolderId
        }],
        name: parentData.Name || getMessage(parentData.name),
        label: 'SearchEngine.folderIn',
        key: pathkey,
        folderPath: folderPathString,
        type: 'back',
        folderLevel: folderLevel.current,
        topFolderId,
        controlType: 'edoc2SelectFolder'
      })
    }
  }

  const getChildFolder = async ({ level = 2, fileSearchid, searchFolderId = '1', folderPath = '1\\', newParams }, type?) => {
    $loading(true)
    let res, fileSearchType = 'all'
    if (fileSearchid == '1') {
      fileSearchType = 'enterprise'
    } else if (fileSearchid == '7') {
      fileSearchType = 'team'
    } else if (fileSearchid == topPersonalFolderId) {
      fileSearchType = 'person'
    }

    let folderparams = {
      ...params,
      ...newParams,
      FacetLevel: level,
      IsFacetFilePath: true,
      IsSelectFolderName: true,
      folderPath,
      folderId: searchFolderId,
      fileSearchType
    }
    if (params.IndexName == 'folder') {
      folderparams.SectionField = 'folderpath'
      folderparams.advancedSearch = advancedSearch
    } else {
      folderparams.SectionField = 'facetfilepath'
    }
    if (configEvents.current?.onCategoryParamsFormat) {
      folderparams = configEvents.current.onCategoryParamsFormat(folderparams)
    }
    if (configEvents.current?.onCategoryRequest) {
      res = await configEvents.current.onCategoryRequest(folderparams)
    } else {
      res = await getPaths(folderparams)
    }
    if (configEvents.current?.onCategoryData) {
      res = await configEvents.current.onCategoryData(res)
    }
    if (res.Code == 0) {
      if (res.SectionList.length > 0) {
        const newFolders = res.SectionList.filter(ele => ele.Name).map(item => {
          const { folderId, parentId } = getFolderId(item.Value)
          return {
            ...item,
            id: folderId,
            folderId,
            parentId,
            folderPath: item.Value
          }
        })
        $childFolder(newFolders)
        if (!type) {

          $allData(data => {
            if (value) {
              return lodash.uniq([...data, ...newFolders, { id: value?.value?.[0]?.folderid, name: value?.name }])
            }
            return lodash.uniq([...data, ...newFolders])
          })
        }
        $loading(false)
        return newFolders
      } else {
        $loading(false)
        $childFolder([])
        return []
      }
    } else if (res.result == 0 && advancedSearch && params.IndexName == 'folder') {
      if (res.docListInfo && res.docListInfo.FoldersInfo.length > 0) {
        const newFolders = res.docListInfo.FoldersInfo.filter(ele => ele.name).map(item => {
          return {
            ...item,
            folderId: item.id,
            parentId: item.parentFolderId,
            folderPath: item.path
          }
        })

        $childFolder(newFolders)
        if (!type) {
          $allData(data => {
            if (value) {
              return lodash.uniq([...data, ...newFolders, { id: value?.value?.[0]?.folderid, name: value?.name }])
            }
            return lodash.uniq([...data, ...newFolders])
          })
        }
        $loading(false)
        return newFolders
      } else {
        $loading(false)
        $childFolder([])
        return []
      }
    } else {
      $loading(false)
      $childFolder([])
      return []
    }

  }


  // 每次点击子文件夹都要保存parentId
  const setParamsId = (item) => {
    folderLevel.current += 1

    $topfolderItem({
      type: folderLevel.current,
      ...item,
    })
    onChange({
      value: [{
        folderid: item.folderId
      }],
      name: item.Name || item.name,
      label: 'SearchEngine.folderIn',
      key: pathkey,
      folderPath: item.folderPath,
      folderLevel: folderLevel.current,
      topFolderId,
      controlType: 'edoc2SelectFolder'
    })

    $currentFolderId(item.parentId)
    let metaSearchWhere = `(filepath:${item.parentId} AND NOT folderid:${item.parentId})`
    if (params.IndexName == 'folder') {
      metaSearchWhere = `(folderpath:${item.parentId} AND NOT folderid:${item.parentId})`
    }
    if (!searchResult) {
      getChildFolder({
        fileSearchid: topFolderId,
        level: folderLevel.current,
        searchFolderId: item.folderId,
        folderPath: item.folderPath,
        newParams: {
          ...params,
          SearchWhere: metaSearchWhere
        }
      })
    }
  }

  const newTopFolder = useMemo(() => {
    let topFolderCopy = [...topFolder]
    if (searchResult) {
      if ((parentTopFolderId && parentTopFolderId == '1')) {
        topFolderCopy = topFolderCopy.filter(item => item.id == '1')
      }
      if (parentTopFolderId && parentTopFolderId == '7') {
        topFolderCopy = topFolderCopy.filter(item => item.id == '7')
      }
      if (parentTopFolderId && parentTopFolderId == String(topPersonalFolderId)) {
        topFolderCopy = topFolderCopy.filter(item => item.id == topPersonalFolderId)
      }
    }
    if (!showTeam) {
      topFolderCopy = topFolderCopy.filter(item => item.id !== '7')
    }
    if (!showPerson) {
      topFolderCopy = topFolderCopy.filter(item => item.id != topPersonalFolderId)
    }
    return topFolderCopy
  }, [showTeam, showPerson, params])

  const showBackLevel = useMemo(() => {
    if (searchResult) {
      // 搜索结果
      if (parentFolderLevel) {
        // 有folderLevel, 代表高级搜索的是所在目录, 没有就是所在目录没有值
        if (value && value.folderLevel) {
          return parentFolderLevel < value.folderLevel
        } else if (!value || !value.value) {
          // 点击重置或者清空
          return false
        } else {
          return folderLevel.current > 2
        }
      } else {
        if (topFolderId == topPersonalFolderId) {
          // 个人库从3开始,所以大于3
          return folderLevel.current > 3
        }
        return folderLevel.current > 2
      }
    } else {
      // 搜索入口
      if (topFolderId == topPersonalFolderId) {
        // 个人库从3开始,所以大于3
        return folderLevel.current > 3
      }
      return folderLevel.current > 2
    }

  }, [topFolderId, folderLevel.current, value])

  useImperativeHandle(ref, () => {
    return {
      getData: (newParams) => {
        getChildFolder({
          fileSearchid: topFolderId,
          level: topfolderItem?.type,
          searchFolderId: topfolderItem?.id,
          folderPath: topfolderItem?.folderPath,
          newParams
        })
      }
    }
  }, [topfolderItem, topFolderId])

  const getChildData = (path) => {
    if (path.value?.[0]?.folderid == '7') {
      getTeams()
      folderLevel.current = 2
    } else {
      getChildFolder({
        fileSearchid: path.topFolderId,
        level: path.folderLevel,
        searchFolderId: path.value[0].folderid,
        folderPath: path.folderPath,
        newParams: params
      })
      folderLevel.current = path.folderLevel
    }
  }

  // 点击企业库 团队库 个人库
  const clickTopFolder = (item) => {
    if (searchResult && parentTopFolderId) {
      return
    }
    if (item.id == '1') {
      // 当在右侧, 触发onchange后会在useImperativeHandle那里的getdata获取子级
      // 当是高级搜索的所在目录时,就得在这里获取子级
      if (searchResult) {
        $topfolderItem({
          type: 2,
          ...item,
        })
      } else {
        getChildFolder({
          fileSearchid: item.id,
          level: 2,
          searchFolderId: item.id,
          folderPath: item.folderPath,
          newParams: {}
        })
      }
      folderLevel.current = 2
    } else if (item.id == 7) {
      getTeams()
      folderLevel.current = 2
      $topfolderItem({
        type: 2,
        ...item,
      })
    } else {
      if (searchResult) {
        $topfolderItem({
          type: 3,
          ...item,
        })
      } else {
        getChildFolder({
          fileSearchid: item.id,
          level: 3,
          searchFolderId: item.id,
          folderPath: item.folderPath,
          newParams: {}
        })
      }
      folderLevel.current = 3
    }
    $topFolderId(item.id)

    onChange({
      value: [{
        folderid: item.id
      }],
      name: getMessage(item.name),
      label: 'SearchEngine.folderIn',
      key: pathkey,
      folderPath: item.folderPath,
      folderLevel: folderLevel.current,
      topFolderId: item.id,
      controlType: 'edoc2SelectFolder'
    })
  }
  // 点击所在目录
  const clickBelongCategory = () => {
    if (!searchResult) {
      let parsedItems: { parentTopFolderId: string } = { parentTopFolderId: '' }
      // 内嵌和大视图的高级搜索-所在目录搜索之后不会重新渲染,因此当再点击所在目录的时候,左侧选中项显示错误
      const initmetaitems = localStorage.getItem('_searchEngineStatus') || sessionStorage.getItem('_searchEngineStatus')
      if (initmetaitems) {
        parsedItems = JSON.parse(initmetaitems)
      }

      let item = topFolder[0], customFolderId = '1'
      if (parentTopFolderId || parsedItems.parentTopFolderId) {
        if (parentTopFolderId) {
          item = topFolder.find(ele => ele.id == parentTopFolderId)
          customFolderId = parentTopFolderId
        } else if (parsedItems.parentTopFolderId) {
          item = topFolder.find(ele => ele.id == parsedItems.parentTopFolderId)
          customFolderId = parsedItems.parentTopFolderId
        }
        // 如果有值,代表已经搜索过了,那么直接赋值topFolderId,获取子级,但不走onchange,那么显示数据就不会变
        if (value && value.value) {
          $topFolderId(customFolderId)
          getChildData({
            value: [{folderid: customFolderId}],
            topFolderId: customFolderId,
            folderLevel: customFolderId == '1'?2:3,
            folderPath: customFolderId == '1'?topFolder[0].folderPath : topFolder[2].folderPath,
          })
          
        } else {
          clickTopFolder(item)
        }
      } else {
        // 这里是第一次点击
        clickTopFolder(item)
      }
    } else if (value?.value?.[0]?.folderid) {
      getChildData({
        value: [{folderid: value.value?.[0]?.folderid}],
        topFolderId: parentTopFolderId || topFolderId,
        folderLevel: value.folderLevel,
        folderPath: value.folderPath,
      })
    } else {
      // 清空或者重置后,需要根据高级搜索那里的条件来获取所在目录, 此时只能从缓存中获取数据
      const orignmetaData = searchEngineData.metaData
      if (orignmetaData && (orignmetaData?.file || orignmetaData?.folder)) {
        const metaData = config.IndexName == 'file' ? orignmetaData.file : orignmetaData.folder
        const path = metaData.find(ele => ele.key.toLowerCase() == 'filepath' || ele.key.toLowerCase() == 'folderpath')
        // 高级搜索中直接点击搜索,path是undefined, 就会报错
        if (path && path.value && path.value.length > 0) {
          $allData(data => {
            return lodash.uniq([...data, { id: path?.value?.[0]?.folderid, name: path?.name }])
          })
          getChildData(path)
        } else {
          // 直接点击高级搜索, 没有path,那么默认点击企业库
          clickTopFolder({
            id: '1',
            folderPath: '1\\',
          })
        }
      } else {
        // 普通搜索时
        clickTopFolder({
          id: '1',
          folderPath: '1\\',
        })
      }
    }
  }

  const folderContainer = <div className='folderContainerOverlay'>
    <div className='topFolderContainer'>
      {
        newTopFolder.map(item => {
          return <div className={`${topFolderId == item.id ? 'selectTopFolder' : ''}`}
            key={item.id}
            onClick={() => clickTopFolder(item)}
          >
            <InbizIcon type={item.iconType} style={{ marginRight: 8, marginLeft: 16, fontSize: 16 }} />
            <TextWidget>{item.name}</TextWidget>
          </div>
        })
      }
    </div>
    <div className='childFolder'>
      <Spin spinning={loading}>
        {showBackLevel && <div className='backLastLevel' onClick={backLastLevel}>
          <InbizIcon type='icon-ic-zuofan' />
          <TextWidget>
            SearchResultEngine.backLastLvel
          </TextWidget>
        </div>}
        <div className='childFolderContainer' >
          {
            childFolder.length == 0 && <Empty
              description={getMessage('SearchResultEngine.noData')}
              image={<InbizIcon type="icon-ic-zanwushuju" />}
            />
          }
          {
            childFolder.map((item, index) => {
              return <div
                className={`childfolderItem`}
                style={{ cursor: 'pointer' }}
                key={item.folderId + '' + index}
                onClick={() => setParamsId(item)}
              >
                <Typography.Text title={item.Name || item.name} ellipsis style={{ width: 211 }}> <InbizIcon type='icon-folder1' style={{ marginRight: 6, fontSize: 16, marginLeft: 10 }} />
                  <TextWidget>{item.Name || item.name}</TextWidget>
                  {searchResult && !isNaN(item.Count) && <span>({item.Count})</span>}
                </Typography.Text>
              </div>
            })
          }
        </div>
      </Spin>
    </div>
  </div>

  if (params.IndexName == 'folder') {
    return <Select
      placeholder={getMessage('SearchEngine.pleaseInput')}
      value={value?.id || value?.value?.[0]?.folderid}
      onChange={(val, options) => {
        onChange({
          value: [{
            folderid: val
          }],
          name: options.title,
          label: 'SearchEngine.folderIn',
          key: pathkey,
          folderPath: val,
          folderLevel: folderLevel.current,
          topFolderId: val,
          controlType: 'edoc2SelectFolder'
        })
      }}
    >
      {
        newTopFolder.map(ele => {
          return <Option key={ele.id} title={getMessage(ele.name)}>{<TextWidget>{`${ele.name}`}</TextWidget>}</Option>
        })
      }
    </Select>
  }

  return (
    <Popover
      placement="bottomLeft"
      content={folderContainer}
      trigger="click"
      overlayClassName='folderContainerPopover'
    >
      <Select
        placeholder={getMessage('SearchEngine.pleaseInput')}
        open={false}
        onClick={clickBelongCategory}
        value={value?.name} />
    </Popover>
  )
}, { forwardRef: true })
